home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1991 / 01 / vgacycle.asm < prev    next >
Assembly Source File  |  1990-11-11  |  7KB  |  253 lines

  1. ; *** Listing 1 ***
  2. ;
  3. ; Fills a band across the screen with vertical bars in all 256
  4. ; attributes, then cycles a portion of the palette until a key is
  5. ; pressed.
  6. ; Assemble with MASM 5.1 or TASM 2.0.
  7.  
  8. USE_BIOS equ    0      ;set to 1 to use BIOS functions to access the
  9.             ; DAC, 0 to read and write the DAC directly
  10. GUARD_AGAINST_INTS equ 0 ;1 to turn off interrupts and set write index
  11.             ; before loading each DAC location, 0 to rely
  12.             ; on the DAC auto-incrementing
  13. WAIT_VSYNC equ    1    ;set to 1 to wait for the leading edge of
  14.             ; vertical sync before accessing the DAC, 0
  15.             ; not to wait
  16. NOT_8088 equ    0    ;set to 1 to use REP INSB and REP OUTSB when
  17.             ; accessing the  DAC directly, 0 to use
  18.             ; IN/STOSB and LODSB/OUT
  19. CYCLE_SIZE equ    256    ;# of DAC locations to cycle, 256 max
  20. SCREEN_SEGMENT equ 0a000h ;mode 13h display memory segment
  21. SCREEN_WIDTH_IN_BYTES equ 320 ;# of bytes across the screen in mode 13h
  22. INPUT_STATUS_1 equ 03dah ;input status 1 register port
  23. DAC_READ_INDEX equ 03c7h  ;DAC Read Index register
  24. DAC_WRITE_INDEX equ 03c8h ;DAC Write Index register
  25. DAC_DATA equ    03c9h      ;DAC Data register
  26.  
  27. if NOT_8088
  28.     .286
  29. endif    ;NOT_8088
  30.  
  31.     .model    small
  32.     .stack    100h
  33.     .data
  34. ;Storage for all 256 DAC locations, organized as one three-byte
  35. ; (actually three 6-bit values; upper two bits of each byte aren't
  36. ; significant) RGB triplet per color.
  37. PaletteTemp    db    256*3 dup(?)
  38.     .code
  39. start:
  40.     mov    ax,@data
  41.     mov    ds,ax
  42.  
  43. ;Select VGA's standard 256-color graphics mode, mode 13h.
  44.     mov    ax,0013h    ;AH = 0: set mode function,
  45.     int    10h        ; AL = 13h: mode # to set
  46.  
  47. ;Read all 256 DAC locations into PaletteTemp (3 6-bit values, one
  48. ; each for red, green, and blue, per DAC location).
  49.  
  50. if WAIT_VSYNC
  51. ;Wait for the leading edge of the vertical sync pulse; this ensures
  52. ; that we read the DAC starting during the vertical non-display
  53. ; period.
  54.     mov    dx,INPUT_STATUS_1
  55. WaitNotVSync:            ;wait to be out of vertical sync
  56.     in    al,dx
  57.     and    al,08h
  58.     jnz    WaitNotVSync
  59. WaitVSync:            ;wait until vertical sync begins
  60.     in    al,dx
  61.     and    al,08h
  62.     jz    WaitVSync
  63. endif    ;WAIT_VSYNC
  64.  
  65. if USE_BIOS
  66.     mov    ax,1017h    ;AH = 10h: set DAC function,
  67.                 ; AL = 17h: read DAC block subfunction
  68.     sub    bx,bx        ;start with DAC location 0
  69.     mov    cx,256        ;read out all 256 locations
  70.     mov    dx,seg PaletteTemp
  71.     mov    es,dx
  72.     mov    dx,offset PaletteTemp ;point ES:DX to array in which
  73.                 ; the DAC values are to be stored
  74.     int    10h        ;read the DAC
  75. else    ;!USE_BIOS
  76.  if GUARD_AGAINST_INTS
  77.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  78.     mov    di,seg PaletteTemp
  79.     mov    es,di
  80.     mov    di,offset PaletteTemp ;dump the DAC into this array
  81.     sub    ah,ah        ;start with DAC location 0
  82. DACStoreLoop:
  83.     mov    dx,DAC_READ_INDEX
  84.     mov    al,ah
  85.     cli
  86.     out    dx,al        ;set the DAC location #
  87.     mov    dx,DAC_DATA
  88.     in    al,dx        ;get the red component
  89.     stosb
  90.     in    al,dx        ;get the green component
  91.     stosb
  92.     in    al,dx        ;get the blue component
  93.     stosb
  94.     sti
  95.     inc    ah
  96.     loop    DACStoreLoop
  97.  else    ;!GUARD_AGAINST_INTS
  98.     mov    dx,DAC_READ_INDEX
  99.     sub    al,al
  100.     out    dx,al        ;set the initial DAC location to 0
  101.     mov    di,seg PaletteTemp
  102.     mov    es,di
  103.     mov    di,offset PaletteTemp ;dump the DAC into this array
  104.     mov    dx,DAC_DATA
  105.   if NOT_8088
  106.     mov    cx,CYCLE_SIZE*3
  107.     rep    insb        ;read CYCLE_SIZE DAC locations at once
  108.   else    ;!NOT_8088
  109.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  110. DACStoreLoop:
  111.     in    al,dx        ;get the red component
  112.     stosb
  113.     in    al,dx        ;get the green component
  114.     stosb
  115.     in    al,dx        ;get the blue component
  116.     stosb
  117.     loop    DACStoreLoop
  118.   endif    ;NOT_8088
  119.  endif    ;GUARD_AGAINST_INTS
  120. endif    ;USE_BIOS
  121.  
  122. ;Draw a series of 1-pixel-wide vertical bars across the screen in
  123. ; attributes 1 through 255.
  124.     mov    ax,SCREEN_SEGMENT    
  125.     mov    es,ax
  126.     mov    di,50*SCREEN_WIDTH_IN_BYTES ;point ES:DI to the start
  127.                         ; of line 50 on the screen
  128.     cld
  129.     mov    dx,100            ;draw 100 lines high
  130. RowLoop:
  131.     mov    al,1            ;start each line with attr 1
  132.     mov    cx,SCREEN_WIDTH_IN_BYTES ;do a full line across
  133. ColumnLoop:
  134.     stosb                ;draw a pixel
  135.     add    al,1            ;increment the attribute
  136.     adc    al,0            ;if the attribute just turned
  137.                     ; over to 0, increment it to 1
  138.                     ; because we're not going to
  139.                     ; cycle DAC location 0, so
  140.                     ; attribute 0 won't change
  141.     loop    ColumnLoop
  142.     dec    dx
  143.     jnz    RowLoop
  144.  
  145. ;Cycle the specified range of DAC locations until a key is pressed.
  146. CycleLoop:
  147. ;Rotate colors 1-255 one position in the PaletteTemp array;
  148. ; location 0 is always left unchanged so that the background
  149. ; and border don't change.
  150.     push    word ptr PaletteTemp+(1*3)    ;set aside PaletteTemp
  151.     push    word ptr PaletteTemp+(1*3)+2    ; setting for attr 1
  152.     mov    cx,254                
  153.     mov    si,offset PaletteTemp+(2*3)
  154.     mov    di,offset PaletteTemp+(1*3)
  155.     mov    ax,ds
  156.     mov    es,ax
  157.     mov    cx,254*3/2
  158.     rep    movsw            ;rotate PaletteTemp settings
  159.                     ; for attrs 2 through 255 to
  160.                     ; attrs 1 through 254
  161.     pop    bx            ;get back original settings
  162.     pop    ax            ; for attribute 1 and move
  163.     stosw                ; them to the PaletteTemp
  164.     mov    es:[di],bl        ; location for attribute 255
  165.  
  166. if WAIT_VSYNC
  167. ;Wait for the leading edge of the vertical sync pulse; this ensures
  168. ; that we reload the DAC starting during the vertical non-display
  169. ; period.
  170.     mov    dx,INPUT_STATUS_1
  171. WaitNotVSync2:            ;wait to be out of vertical sync
  172.     in    al,dx
  173.     and    al,08h
  174.     jnz    WaitNotVSync2
  175. WaitVSync2:            ;wait until vertical sync begins
  176.     in    al,dx
  177.     and    al,08h
  178.     jz    WaitVSync2
  179. endif    ;WAIT_VSYNC
  180.  
  181. if USE_BIOS
  182. ;Set the new, rotated palette.
  183.     mov    ax,1012h    ;AH = 10h: set DAC function,
  184.                 ; AL = 12h: set DAC block subfunction
  185.     sub    bx,bx        ;start with DAC location 0
  186.     mov    cx,CYCLE_SIZE    ;# of DAC locations to set
  187.     mov    dx,seg PaletteTemp
  188.     mov    es,dx
  189.     mov    dx,offset PaletteTemp ;point ES:DX to array from which
  190.                 ; to load the DAC
  191.     int    10h        ;load the DAC
  192. else    ;!USE_BIOS
  193.  if GUARD_AGAINST_INTS
  194.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  195.     mov    si,offset PaletteTemp ;load the DAC from this array
  196.     sub    ah,ah        ;start with DAC location 0
  197. DACLoadLoop:
  198.     mov    dx,DAC_WRITE_INDEX
  199.     mov    al,ah
  200.     cli
  201.     out    dx,al        ;set the DAC location #
  202.     mov    dx,DAC_DATA
  203.     lodsb
  204.     out    dx,al        ;set the red component
  205.     lodsb
  206.     out    dx,al        ;set the green component
  207.     lodsb
  208.     out    dx,al        ;set the blue component
  209.     sti
  210.     inc    ah
  211.     loop    DACLoadLoop
  212.  else    ;!GUARD_AGAINST_INTS
  213.     mov    dx,DAC_WRITE_INDEX
  214.     sub    al,al
  215.     out    dx,al        ;set the initial DAC location to 0
  216.     mov    si,offset PaletteTemp ;load the DAC from this array
  217.     mov    dx,DAC_DATA
  218.   if NOT_8088
  219.     mov    cx,CYCLE_SIZE*3
  220.     rep    outsb        ;load CYCLE_SIZE DAC locations at once
  221.   else    ;!NOT_8088
  222.     mov    cx,CYCLE_SIZE    ;# of DAC locations to load
  223. DACLoadLoop:
  224.     lodsb
  225.     out    dx,al        ;set the red component
  226.     lodsb
  227.     out    dx,al        ;set the green component
  228.     lodsb
  229.     out    dx,al        ;set the blue component
  230.     loop    DACLoadLoop
  231.   endif    ;NOT_8088
  232.  endif    ;GUARD_AGAINST_INTS
  233. endif    ;USE_BIOS
  234.  
  235. ;See if a key has been pressed.
  236.     mov    ah,0bh        ;DOS check standard input status fn
  237.     int    21h
  238.     and    al,al        ;is a key pending?
  239.     jz    CycleLoop    ;no, cycle some more
  240.  
  241. ;Clear the keypress.
  242.     mov    ah,1        ;DOS keyboard input fn
  243.     int    21h
  244.  
  245. ;Restore text mode and done.
  246.     mov    ax,0003h    ;AH = 0: set mode function,
  247.     int    10h        ; AL = 03h: mode # to set
  248.     mov    ah,4ch        ;DOS terminate process fn
  249.     int    21h
  250.  
  251.     end    start
  252.  
  253.